package cc.mcyx.ychat.websocket

import cc.mcyx.ychat.service.impl.RedisService
import cc.mcyx.ychat.websocket.event.SubscribeWsEvent
import cc.mcyx.ychat.websocket.event.WsData
import cn.hutool.core.annotation.AnnotationUtil
import cn.hutool.core.util.ObjectUtil
import com.corundumstudio.socketio.SocketIOServer
import com.corundumstudio.socketio.annotation.OnConnect
import com.corundumstudio.socketio.annotation.OnDisconnect
import com.corundumstudio.socketio.annotation.OnEvent
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.context.event.EventListener
import org.springframework.stereotype.Component
import java.lang.reflect.Method
import java.util.*

@Component
@SubscribeWsEvent
class RootWebSocket(private val sis: SocketIOServer) {

    var tempUID: MutableMap<Int, MutableSet<UUID>> = mutableMapOf()

    @Autowired
    lateinit var redisService: RedisService

    @EventListener
    fun annotationSubscribe(appReadyEvent: ApplicationReadyEvent) {
        // 将所有对应事件方法进行注册
        appReadyEvent.applicationContext.getBeansWithAnnotation(SubscribeWsEvent::class.java).values.forEach {
            it.javaClass.declaredMethods.forEach { method: Method ->
                if (AnnotationUtil.hasAnnotation(method, OnEvent::class.java)) {
                    val en = method.getAnnotation(OnEvent::class.java).value
                    sis.addEventListener(en, Any::class.java) { ioc, t, rq -> method.invoke(it, WsData(ioc, t, rq)) }
                }
                if (AnnotationUtil.hasAnnotation(method, OnConnect::class.java)) {
                    sis.addConnectListener { ioc -> method.invoke(it, ioc) }
                }
                if (AnnotationUtil.hasAnnotation(method, OnDisconnect::class.java)) {
                    sis.addDisconnectListener { ioc -> method.invoke(it, ioc) }
                }
            }
        }
    }

    fun isAccept(uuid: UUID): Boolean {
        return ObjectUtil.isNotNull(redisService.getData("ws-accept-${uuid}"))
    }

    fun closeAccept(uuid: UUID): Boolean {
        redisService.delData("wsa-${uuid}")
        return true
    }

    fun acceptToUid(uuid: UUID): Int {
        return redisService.getData("wsa-${uuid}") as Int
    }

    fun accept(uuid: UUID, uid: Int) {
        redisService.setData("wsa-${uuid}", uid)
    }

    fun getUidSession(uid: Int): List<UUID> {
        return mutableListOf<UUID>().also {
            // 解决 缓存问题
        }
    }
}